package com.my.netty.optimize.server.handler;

import com.my.netty.optimize.message.RpcRequestMessage;
import com.my.netty.optimize.message.RpcResponseMessage;
import com.my.netty.optimize.server.service.ServicesFactory;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.lang.reflect.Method;

@ChannelHandler.Sharable
public class RpcRequestMessageHandler extends SimpleChannelInboundHandler<RpcRequestMessage> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcRequestMessage msg) throws Exception {
        //请求消息中获取接口全类名，参数
        String interfaceName = msg.getInterfaceName();
        String methodName = msg.getMethodName();
        Class[] parameterTypes = msg.getParameterTypes();
        Object[] parameterValues = msg.getParameterValue();
        Object ret;

        RpcResponseMessage responseMessage = new RpcResponseMessage();
        responseMessage.setSequenceId(msg.getSequenceId());
        try {
            //找到接口class
            Class<?> interfaceClass = Class.forName(interfaceName);
            //找到实现类实例
            Object instance = ServicesFactory.getInstance(interfaceClass);
            //调用实现类执行方法
            Method method = instance.getClass().getMethod(methodName, parameterTypes);
            ret = method.invoke(instance, parameterValues);
            //执行成功
            responseMessage.setReturnValue(ret);
        } catch (Exception e) {
            e.printStackTrace();
            //执行出异常，这里直接将Exception放到msg发回给客户端可能导致消息体超过LengthFieldBasedFrameDecoder最大限制然后报错
//            responseMessage.setExceptionValue(e);
            //这里只返回简略的必要异常信息
            responseMessage.setExceptionValue(new Exception("RPC异常：" + e.getCause().getMessage()));
        } finally {
            //响应返回值
            ctx.writeAndFlush(responseMessage);
        }
    }
}
